﻿using System.Collections.Generic;
using UnityEngine;

namespace NpcFramework
{
    public class NpcWayManager
    {
        public Dictionary<int, NpcWayPathData> NpcWayPathDatas = new Dictionary<int, NpcWayPathData>();

        public void Dispose()
        {
            if (NpcWayPathDatas !=null)
            {
                NpcWayPathDatas.Clear();
                NpcWayPathDatas = null;
            }
        }
        public void AddWayPathData(NpcWayPathData npcWayPathData)
        {
            if (!NpcWayPathDatas.ContainsKey(npcWayPathData.WayID))
            {
                NpcWayPathDatas.Add(npcWayPathData.WayID,npcWayPathData);
            }
            else
            {
                UnityEngine.Debug.LogError("重复的路径ID "+npcWayPathData.WayID.ToString());
            }
        }

        public NpcWayPointData GetWayPoint(int wayID, int pointIndex)
        {
            if (!NpcWayPathDatas.ContainsKey(wayID))
            {
                UnityEngine.Debug.LogError("没有此路径："+wayID);
                return null;
            }

            return NpcWayPathDatas[wayID].WayPoints[pointIndex];
        }

        public NpcWayPointData FindNearlyPointData(int wayID, Vector3 currentPos, bool npcDataFacing)
        {
            if (!NpcWayPathDatas.ContainsKey(wayID))
            {
                UnityEngine.Debug.LogError("没有此路径："+wayID);
                return null;
            }

            NpcWayPointData returnData = null;
            var datas = NpcWayPathDatas[wayID];
            float mindistance = 0;
            var mainCharactor = NFMgr.DataManager.GetNpcData(NpcDataManager.MainCharacterId);
            var mainCharactorForward = mainCharactor.Destination - mainCharactor.Position;
            foreach (var data in datas.WayPoints)
            {
                if (data.IsBranchPoint)
                {
                    continue;
                }

                if (NFMgr.TrafficManager.IsTrafficLightPoint(data.WayId,data.Index))
                {
                    // 红绿灯上不生成，防止闯红灯
                    continue;
                }
                
                var distance = Vector3.Distance(currentPos, data.Position);
                var direction = (data.Position - currentPos).normalized;
                var isFacing = Vector3.Dot(mainCharactorForward.normalized, direction) > 0;//目标点是否与主角朝向相向
               
                if ((mindistance == 0 || distance < mindistance) && isFacing == npcDataFacing)
                {
                    returnData = data;
                    mindistance = distance;
                }
            }

            return returnData;
        }

        public NpcWayPointData GetNextWayPoint(int wayID,int pointIndex,bool branch = true)
        {
            if (!NpcWayPathDatas.ContainsKey(wayID))
            {
                return null;
            }

            var pointData = NpcWayPathDatas[wayID].WayPoints[pointIndex];
            var nextIndex = pointData.NextIndex;
            if (branch)
            {
                if (pointData.BranchIndex != null && pointData.BranchIndex.Count > 0)
                {
                    int idx = Random.Range(0, pointData.BranchIndex.Count + 1);
                    if (idx > 0)
                    {
                        if (pointData.BranchIndex[idx - 1].BranchType == BranchType.Forward)
                        {
                            nextIndex = pointData.BranchIndex[idx - 1].Index;
                        }
                    }
                }
            }

            if (nextIndex < 0)
            {
                return null;
            }
            
            return  NpcWayPathDatas[wayID].WayPoints[nextIndex];
        }

        public NpcWayPointData GetPreWayPoint(int wayID, int pointIndex,bool branch = true)
        {
            if (!NpcWayPathDatas.ContainsKey(wayID))
            {
                return null;
            }

            NpcWayPathData pathData = NpcWayPathDatas[wayID];
            if (pointIndex < 0 || pointIndex > pathData.WayPoints.Count - 1)
            {
                return null;
            }
            
            var pointData = pathData.WayPoints[pointIndex];
            var prevIndex = pointData.PrevIndex;

            if (pointData.IsBranchPoint)
            {
                prevIndex = pointData.NextIndex;    // 如果是分支则不处理前置
            }

            if (branch)
            {
                if (pointData.BranchIndex != null && pointData.BranchIndex.Count > 0)
                {
                    int idx = Random.Range(0, pointData.BranchIndex.Count + 1);
                    if (idx > 0)
                    {
                        if (pointData.BranchIndex[idx - 1].BranchType == BranchType.Backward)
                        {
                            prevIndex = pointData.BranchIndex[idx - 1].Index;
                        }
                    }
                }
            }

            if (prevIndex < 0)
            {
                return null;
            }

            return NpcWayPathDatas[wayID].WayPoints[prevIndex];
        }

        public void GetCarBornPoints(List<NpcWayPointData> list)
        {
            if (NpcWayPathDatas!=null)
            {
                var enumerator = NpcWayPathDatas.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    var value = enumerator.Current.Value;
                    if (value.WayPathType == WayPathType.Car)
                    {
                        foreach (var point in value.WayPoints)
                        {
                            if (point.IsGenerateCar)
                            {
                                list.Add(point);
                            }
                        }
                    }
                }
                enumerator.Dispose();
            }
        }

        public void GetNpcBornPoints(List<NpcWayPointData> list)
        {
            if (NpcWayPathDatas!=null)
            {
                var enumerator = NpcWayPathDatas.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    var value = enumerator.Current.Value;
                    if (value.WayPathType == WayPathType.WalkNpc)
                    {
                        foreach (var point in value.WayPoints)
                        {
                            if (point.IsGenerateNpc)
                            {
                                list.Add(point);
                            }
                        }
                    }
                }
                enumerator.Dispose();
            }
        }

       
    }
}
